<!-- 底部弹窗需要组件（分享） -->

<template>
	<view v-if="isShow" ref="ani" class="uni-transition" :class="[ani.in]" :style="'transform:' + transform + ';' + stylesObject"
		@click="change">
		<slot></slot>
	</view>
</template>

<script>
// #ifdef APP-NVUE
const animation = uni.requireNativePlugin('animation');
// #endif
/**
 * Transition 过渡动画
 * @description 简单过渡动画组件
 * @tutorial https://ext.dcloud.net.cn/plugin?id=985
 * @property {Boolean} show = [false|true] 控制组件显示或隐藏
 * @property {Array} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
 *  @value fade 渐隐渐出过渡
 *  @value slide-top 由上至下过渡
 *  @value slide-right 由右至左过渡
 *  @value slide-bottom 由下至上过渡
 *  @value slide-left 由左至右过渡
 *  @value zoom-in 由小到大过渡
 *  @value zoom-out 由大到小过渡
 * @property {Number} duration 过渡动画持续时间
 * @property {Object} styles 组件样式，同 css 样式，注意带’-‘连接符的属性需要使用小驼峰写法如：`backgroundColor:red`
 */
export default {
	name: 'uniTransition',
	props: {
		show: {
			type: Boolean,
			default: false
		},
		modeClass: {
			type: Array,
			default() {
				return []
			}
		},
		duration: {
			type: Number,
			default: 300
		},
		styles: {
			type: Object,
			default() {
				return {}
			}
		}
	},
	data() {
		return {
			isShow: false,
			transform: '',
			ani: {
				in: '',
				active: ''
			}
		};
	},
	watch: {
		show: {
			handler(newVal) {
				if (newVal) {
					this.open()
				} else {
					this.close()
				}
			},
			immediate: true
		}
	},
	computed: {
		stylesObject() {
			let styles = {
				...this.styles,
				'transition-duration': this.duration / 1000 + 's'
			}
			let transfrom = ''
			for (let i in styles) {
				let line = this.toLine(i)
				transfrom += line + ':' + styles[i] + ';'
			}
			return transfrom
		}
	},
	created() {
		uni.showShareMenu({
			withShareTicket: true,
			menus: ['shareAppMessage', 'shareTimeline']
		});

		// this.timer = null
		// this.nextTick = (time = 50) => new Promise(resolve => {
		// 	clearTimeout(this.timer)
		// 	this.timer = setTimeout(resolve, time)
		// 	return this.timer
		// });
	},
	methods: {
		change() {
			this.$emit('click', {
				detail: this.isShow
			})
		},
		open() {
			clearTimeout(this.timer)
			this.isShow = true
			this.transform = ''
			this.ani.in = ''
			for (let i in this.getTranfrom(false)) {
				if (i === 'opacity') {
					this.ani.in = 'fade-in'
				} else {
					this.transform += `${this.getTranfrom(false)[i]} `
				}
			}
			this.$nextTick(() => {
				setTimeout(() => {
					this._animation(true)
				}, 50)
			})

		},
		close(type) {
			clearTimeout(this.timer)
			this._animation(false)
		},
		_animation(type) {
			let styles = this.getTranfrom(type)
			// #ifdef APP-NVUE
			if (!this.$refs['ani']) return
			animation.transition(this.$refs['ani'].ref, {
				styles,
				duration: this.duration, //ms
				timingFunction: 'ease',
				needLayout: false,
				delay: 0 //ms
			}, () => {
				if (!type) {
					this.isShow = false
				}
				this.$emit('change', {
					detail: this.isShow
				})
			})
			// #endif
			// #ifndef APP-NVUE
			this.transform = ''
			for (let i in styles) {
				if (i === 'opacity') {
					this.ani.in = `fade-${type ? 'out' : 'in'}`
				} else {
					this.transform += `${styles[i]} `
				}
			}
			this.timer = setTimeout(() => {
				if (!type) {
					this.isShow = false
				}
				this.$emit('change', {
					detail: this.isShow
				})

			}, this.duration)
			// #endif

		},
		getTranfrom(type) {
			let styles = {
				transform: ''
			}
			this.modeClass.forEach((mode) => {
				switch (mode) {
					case 'fade':
						styles.opacity = type ? 1 : 0
						break;
					case 'slide-top':
						styles.transform += `translateY(${type ? '0' : '-100%'}) `
						break;
					case 'slide-right':
						styles.transform += `translateX(${type ? '0' : '100%'}) `
						break;
					case 'slide-bottom':
						styles.transform += `translateY(${type ? '0' : '100%'}) `
						break;
					case 'slide-left':
						styles.transform += `translateX(${type ? '0' : '-100%'}) `
						break;
					case 'zoom-in':
						styles.transform += `scale(${type ? 1 : 0.8}) `
						break;
					case 'zoom-out':
						styles.transform += `scale(${type ? 1 : 1.2}) `
						break;
				}
			})
			return styles
		},
		_modeClassArr(type) {
			let mode = this.modeClass
			if (typeof (mode) !== "string") {
				let modestr = ''
				mode.forEach((item) => {
					modestr += (item + '-' + type + ',')
				})
				return modestr.substr(0, modestr.length - 1)
			} else {
				return mode + '-' + type
			}
		},
		// getEl(el) {
		// 	console.log(el || el.ref || null);
		// 	return el || el.ref || null
		// },
		toLine(name) {
			return name.replace(/([A-Z])/g, "-$1").toLowerCase();
		}
	}
}
</script>

<style>
.uni-transition {
	transition-timing-function: ease;
	transition-duration: 0.3s;
	transition-property: transform, opacity;
}

.fade-in {
	opacity: 0;
}

.fade-active {
	opacity: 1;
}

.slide-top-in {
	/* transition-property: transform, opacity; */
	transform: translateY(-100%);
}

.slide-top-active {
	transform: translateY(0);
	/* opacity: 1; */
}

.slide-right-in {
	transform: translateX(100%);
}

.slide-right-active {
	transform: translateX(0);
}

.slide-bottom-in {
	transform: translateY(100%);
}

.slide-bottom-active {
	transform: translateY(0);
}

.slide-left-in {
	transform: translateX(-100%);
}

.slide-left-active {
	transform: translateX(0);
	opacity: 1;
}

.zoom-in-in {
	transform: scale(0.8);
}

.zoom-out-active {
	transform: scale(1);
}

.zoom-out-in {
	transform: scale(1.2);
}
</style>
